/*
 * ------------------------------------------
 * 方形闭合跑马灯抽奖 组件化
 * @version  1.0
 * @author   hzyang_fan(hzyang_fan@corp.netease.com)
 * ------------------------------------------
 */

function Marquee(config) {
    this.time = 0;                                                          // 标记抽奖次数
    this.length = 0;                                                        // 标记奖品数
    this.config = config;                                                   // 配置
    this.lastIndex = 0;                                                     // 标记上次抽奖停止位置
    this.container = document.createDocumentFragment();                     // 标记容器
    this._setBox();
    this._bindEvent(this);
}

var mp = Marquee.prototype;

// 设定抽奖区域
mp._setBox = function () {
    var config = this.config;
    var row = config.row;                                                   // 行数
    var column = config.column;                                             // 列数
    var margin = config.margin || 1;                                        // 奖品间隙
    if (!row || !column || row < 3 || column < 3) {
        alert('行数和列数必须不小于3!');
        return;
    }
    var cntWidth = config.width;                                            // 容器总宽度
    var cntHeight = config.height;                                          // 容器总高度
    if (!cntWidth || !cntHeight || cntWidth < 0 || cntHeight < 0) {
        alert('宽度和高度必须不小于0!');
        return;
    }
    var boxWidth = cntWidth - margin * (column - 1);                        // 容器去除间隙宽度
    var boxHeight = cntHeight - margin * (row - 1);                         // 容器去除间隙高度
    var pieceWidth = (boxWidth - boxWidth % column) / column;               // 单个奖品区域宽度
    var pieceHeight = (boxHeight - boxHeight % row ) / row;                 // 单个奖品区域高度
    // 奖品排列设置
    var transit = [];
    for (var i = 0; i < row; i++) {
        transit[i] = [];
        for (var j = 0; j < column; j++) {
            var piece = {};
            piece.x = j * pieceWidth + j * margin;
            piece.y = i * pieceHeight + i * margin;
            if (i > 0 & i < row - 1 & j > 0 & j < column - 1) continue;
            transit[i][j] = piece;
        }
    }
    for (var i = 0; i < row; i++) {
        if (i == row - 1) transit[i].reverse()
    }
    var array = [];
    array = array.concat(transit[0]);
    for (var i = 1; i < row - 1; i++) {
        array = array.concat(transit[i][column - 1])
    }
    array = array.concat(transit[row - 1]);
    for (var i = row - 2; i > 0; i--) {
        array = array.concat(transit[i][0])
    }
    // 抽奖区域渲染
    this.length = array.length;
    var index = 0, prizes = config.prizes;
    // 奖品
    for (var f = 0, l = array.length; f < l; f++) {
        index++;
        var div = document.createElement('div'), convert = '', prize = prizes[f];
        if (prize && prize.img) {
            convert += '<img src="' + prize.img + '" alt="' + prize.text + '" style="display:block;width:' + pieceWidth + 'px;height:' + pieceHeight + 'px;"/>';
            if (prize.href) convert = '<a href="' + prize.href + '" target="_blank" title="' + prize.text + '">' + convert + '</a>';
        } else if (prize && prize.text) {
            convert += prize.text
        }
        convert += '<div class="j-marquee-halo j-marquee-halo' + index + '"></div>';
        div.innerHTML = convert;
        div.className = 'j-marquee-prize j-marquee-prize' + index;
        div.style.cssText = 'width:' + pieceWidth + 'px;height:' + pieceHeight + 'px;line-height:' + pieceHeight + 'px;top:' + array[f].y + 'px;left:' + array[f].x + 'px;';
        this.container.appendChild(div);
    }
    // 抽奖按钮
    var btn = this.btn = document.createElement('div');
    var btnWidth = (column - 2) * pieceWidth + (column - 3) * margin;
    var btnHeight = (row - 2) * pieceHeight + (row - 3) * margin;
    btn.className = 'j-marquee-btn';
    btn.style.cssText = 'width:' + btnWidth + 'px;height:' + btnHeight + 'px;line-height:' + btnHeight + 'px;top:' + (pieceHeight + margin) + 'px;left:' + (pieceWidth + margin) + 'px;';
    this.container.appendChild(btn);
};

// 自定义事件
mp._bindEvent = function (context) {
    if (!context) return;
    // Handles custom event
    context.$on = function (event, fn) {
        if (typeof event === 'object') {
            var _on = arguments.callee;
            for (var key in event) {
                if (event.hasOwnProperty(key)) _on(key, event[key]);
            }
        } else {
            var _handles = context._handles || (context._handles = {}),
                _calls = _handles[event] || (_handles[event] = []);
            _calls.push(fn);
        }
        return context;
    };
    // Relieve custom event
    context.$off = function (event, fn) {
        if (!context._handles) return;
        if (!event) context._handles = {};
        var _handles = context._handles, _calls;

        if (_calls = _handles[event]) {
            if (!fn) {
                _handles[event] = [];
                return context;
            }
            for (var i = 0, l = _calls.length; i < l; i++) {
                if (fn === _calls[i]) {
                    _calls.splice(i, 1);
                    return context;
                }
            }
        }
        return context;
    };
    // Trigger custom events
    context.$emit = function (event) {
        var handles = context._handles, calls, args, type;
        if (!event) return;
        if (typeof event === "object") {
            type = event.type;
            args = event.data || [];
        } else {
            args = Array.prototype.slice.call(arguments);
            type = event;
        }
        if (!handles || !(calls = handles[type])) return context;
        for (var i = 0, len = calls.length; i < len; i++) {
            calls[i].apply(context, args)
        }
        return context;
    }
};

// 节点插入
mp.$inject = function (elem) {
    if (!elem) return;
    var node = $(elem)[0];
    node.innerHTML = '';
    node.appendChild(this.container);
    return this;
};

// 启动
mp.$play = function (info) {
    if (!info.endCycle || info.endCycle < 2 || !info.EndIndex) {
        alert('必须有转动圈数和结束位置，至少转动2圈!');
        return;
    }
    // 获取配置信息
    var self = this,
        index = info.index || 1,                                            // 起始位置
        arr_length = self.length,                                           // 跑马灯个数
        endCycle = info.endCycle,                                           // 转动圈数
        EndIndex = info.EndIndex,                                           // 结束位置
        quick = info.quick ? index + info.quick : 0,                        // 加速位标识
        slow = info.slow || 3;                                              // 减速位标识
    // 开始前准备
    var run = 0,                                                            // 转动次数
        cycle = 0,                                                          // 当前圈数
        flag = false,                                                       // 结束转动标志
        speed = (self.config.speed || 5) * 50,                              // 转动速度
        timer = setInterval(play, speed),                                   // 起始速度
        prevIndex = self.lastIndex || arr_length;                           // 前一位置
    self.time++;
    slow = (EndIndex - slow) <= 0 ? (EndIndex - slow + arr_length) : (EndIndex - slow);
    $(".j-marquee-halo" + prevIndex).removeClass('j-marquee-current');

    // 跑马灯
    function play() {
        run++;
        if (flag == false) {
            // 加速
            if (quick == run) {
                clearInterval(timer);
                timer = setInterval(play, speed / 4);
            }
            // 减速并触发结束
            if (cycle == endCycle - 1 && index == slow) {
                clearInterval(timer);
                flag = true;
                timer = setInterval(play, speed * 1.5);
            }
        }
        //转满1圈index归1
        if (index > arr_length) {
            index = 1;
            cycle++;
        }
        $(".j-marquee-halo" + index).addClass('j-marquee-current');
        if (index > 1) prevIndex = index - 1;
        else prevIndex = arr_length;
        $(".j-marquee-halo" + prevIndex).removeClass('j-marquee-current');
        // 转动结束
        if (flag == true && index == EndIndex) {
            quick = 0;
            self.lastIndex = EndIndex;
            clearInterval(timer);
            self.$emit('end');
        }
        index++;
    }
};




